/**
 * Copyright (C) 2015-2018 IQIYI
 * All rights reserved.
 *
 * Author     : 王海斌
 * E-mail     : wanghaibin@qiyi.com
 * Version    :
 * Date       : Mon 03 Aug 2020 11:42:00 AM CST
 * Destription: 测试getopt_long
 *
 * ./test --add aa bb
 */

#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <getopt.h>

void print_help(const char * proc) {
    printf("Usage %s [OPTION] [args]\n", proc);
    printf("OPTIONS:\n");
    printf("    --add         file1 file2       \"两个参数file1和file2测试\"\n");
    printf("    -c, --create  file              \"显示此帮助.\"\n");
    printf("    -f, --file    file              \"测试使用的文件.\"\n");
    printf("    -h, --help                      \"显示此帮助.\"\n");
    printf("    --verbose                       \"显示详细内容\"\n");

}

int main(int argc, char **argv) {
    int c;
    int digit_optind = 0;  //数字选项序号
    printf("argc=%d\n", argc);

    while (1) {
        int this_option_optind = optind ? optind : 1;   // 当前选项的序号
        int option_index = 0;
        static struct option long_options[] = {
            {"append",  no_argument,       0,  0 },
            {"verbose", no_argument,       0,  0 },
            {"create",  required_argument, 0, 'c'},
            {"file",    required_argument, 0, 'f'},
            {"add",     required_argument, 0,  1 }, // 测试一个关键字带多个参数

            {0,         0,                 0,  0 }
        };
        c = getopt_long(argc, argv, "abc:d:012", long_options, &option_index);
        // 当第三个参数为0 时 获取到对应的长参数时返回值为第四个参数的值
        printf("line=(%d) c=%d, this_option_optind=%d\n",__LINE__, c, this_option_optind);
        if (c == -1) { // 遍历结束
            break;
        }
        switch (c) {
            case 0:
                printf("line=(%d) option %s\n",__LINE__, long_options[option_index].name);
                if (optarg) {
                    printf("  line:(%d) with arg %s\n",__LINE__, optarg);
                }
                printf("\n");
                break;
            case 1:
                {
                    if(NULL!=optarg) {
                        if(argc<=optind || '-'==argv[optind][0]) {
                            return 0;
                        }
                        printf("f1=%s, f2=%s", optarg, argv[optind]);
                    }
                }
                break;
            case '0':
            case '1':
            case '2':
                if (digit_optind != 0 && digit_optind != this_option_optind)
                    printf("digits occur in two different argv-elements.\n");
                printf("line(%d), digit_optind=%d, this_option_optind=%d\n", __LINE__, digit_optind, this_option_optind);
                digit_optind = this_option_optind;
                printf("line(%d) option %c\n",__LINE__, c);
                break;
            case 'a':
                printf("line(%d) option a\n", __LINE__);
                break;
            case 'b':
                printf("line(%d) option b\n", __LINE__);
                break;
            case 'c':
                printf("line(%d) option c with value '%s'\n",__LINE__, optarg);
                break;
            case 'd':
                printf("line(%d) option d with value '%s'\n",__LINE__, optarg);
                break;
            case '?':
                printf("line(%d) option ? with value '%s'\n",__LINE__, optarg);
                break;
            default:
                printf("line(%d) ?? getopt returned character code 0%o ??\n",__LINE__, c);
        }
    }

    if (optind < argc) {
        printf("non-option ARGV-elements: ");
        while (optind < argc)
            printf("%s ", argv[optind++]);
        printf("\n");
    }

    exit(EXIT_SUCCESS);
}

